home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / cross / avra-0.4_src.lha / avra-0.4 / args.c next >
Encoding:
C/C++ Source or Header  |  1999-01-28  |  5.3 KB  |  212 lines

  1. /***********************************************************************
  2.  *  args - Argument reading system
  3.  *  Copyright (C) 1997-1999 Jon Anders Haugum
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  18.  *  Boston, MA 02111-1307, USA.
  19.  *
  20.  *
  21.  *  Author of args can be reached at:
  22.  *     email: jonah@colargol.tihlde.hist.no
  23.  *     Postal address: Jon Anders Haugum
  24.  *                     Øvre Møllenbergsgt 52
  25.  *                     7014 Trondheim
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31.  
  32. #include "misc.h"
  33. #include "args.h"
  34.  
  35.  
  36. struct args *alloc_args(int arg_count)
  37.     {
  38.     struct args *args;
  39.  
  40.     args = malloc(sizeof(struct args));
  41.     if(args)
  42.         {
  43.         args->arg = malloc(sizeof(struct arg) * arg_count);
  44.         if(args->arg)
  45.             {
  46.             args->count = arg_count;
  47.             args->first_data = NULL;
  48.             return(args);
  49.             }
  50.         free(args);
  51.         }
  52.     printf("Error: Unable to allocate memory\n");
  53.     return(NULL);
  54.     }
  55.  
  56.  
  57.  
  58. int read_args(struct args *args, int argc, char *argv[])
  59.     {
  60.     int i, j, k, ok = True, i_old;
  61.     struct data_list **last_data;
  62.  
  63.     args->first_data = NULL;
  64.     last_data = &args->first_data;
  65.     for(i = 1; (i < argc) && ok; i++)
  66.         {
  67.         if(argv[i][0] == '-')
  68.             {
  69.             last_data = &args->first_data;
  70.             if(argv[i][1] == '-')
  71.                 {
  72.                 j = 0;
  73.                 while((args->arg[j].longarg ? strcmp(&argv[i][2], args->arg[j].longarg) : True) && (j != args->count))
  74.                     j++;
  75.                 if(j == args->count)
  76.                     {
  77.                     printf("Error: Unknown option: %s\n", argv[i]);
  78.                     ok = False;
  79.                     }
  80.                 else
  81.                     {
  82.                     switch(args->arg[j].type)
  83.                         {
  84.                         case ARGTYPE_STRING:
  85.                         case ARGTYPE_STRING_MULTISINGLE:
  86.                             if((i + 1) == argc)
  87.                                 {
  88.                                 printf("Error: No argument supplied with option: %s\n", argv[i]);
  89.                                 ok = False;
  90.                                 }
  91.                             else if(args->arg[j].type != ARGTYPE_STRING_MULTISINGLE)
  92.                                 args->arg[j].data = argv[++i];
  93.                             else
  94.                                 ok = add_arg((struct data_list **)&args->arg[j].data, argv[++i]);
  95.                             break;
  96.                         case ARGTYPE_BOOLEAN:
  97.                             args->arg[j].data = (char *)True;
  98.                             break;
  99.                         case ARGTYPE_STRING_MULTI:
  100.                             last_data = (struct data_list **)&args->arg[j].data;
  101.                             break;
  102.                         }
  103.                     }
  104.                 }
  105.             else
  106.                 {
  107.                 // ToDo: Sjekk for enkel -
  108.                 for(k = 1, i_old = i; (argv[i][k] != '\0') && ok && (i == i_old); k++)
  109.                     {
  110.                     j = 0;
  111.                     while((argv[i][k] != args->arg[j].letter) && (j != args->count))
  112.                         j++;
  113.                     if(j == args->count)
  114.                         {
  115.                         printf("Error: Unknown option: -%c\n", argv[i][k]);
  116.                         ok = False;
  117.                         }
  118.                     else
  119.                         {
  120.                         switch(args->arg[j].type)
  121.                             {
  122.                             case ARGTYPE_STRING:
  123.                                 if(argv[i][k + 1] != '\0')
  124.                                     {
  125.                                     printf("Error: Option -%c must be followed by it's argument\n", argv[i][k]);
  126.                                     ok = False;
  127.                                     }
  128.                                 else
  129.                                     {
  130.                                     if((i + 1) == argc)
  131.                                         {
  132.                                         printf("Error: No argument supplied with option: -%c\n", argv[i][k]);
  133.                                         ok = False;
  134.                                         }
  135.                                     else if(args->arg[j].type != ARGTYPE_STRING_MULTISINGLE)
  136.                                         args->arg[j].data = argv[++i];
  137.                                     else
  138.                                         ok = add_arg((struct data_list **)&args->arg[j].data, argv[++i]);
  139.                                     }
  140.                                 break;
  141.                             case ARGTYPE_BOOLEAN:
  142.                                 args->arg[j].data = (char *)True;
  143.                                 break;
  144.                             case ARGTYPE_STRING_MULTI:
  145.                                 last_data = (struct data_list **)&args->arg[j].data;
  146.                                 break;
  147.                             }
  148.                         }
  149.                     }
  150.                 }
  151.             }
  152.         else
  153.             ok = add_arg(last_data, argv[i]);
  154.         }
  155.     return(ok);
  156.     }
  157.  
  158.  
  159. int add_arg(struct data_list **last_data, char *argv)
  160.     {
  161.     struct data_list *data;
  162.  
  163.     while(*last_data) last_data = &((*last_data)->next);
  164.     data = malloc(sizeof(struct data_list));
  165.     if(data)
  166.         {
  167.         data->next = NULL;
  168.         data->data = argv;
  169.         *last_data = data;
  170.         last_data = &data->next;
  171.         }
  172.     else
  173.         {
  174.         printf("Error: Unable to allocate memory\n");
  175.         return(False);
  176.         }
  177.     return(True);
  178.     }
  179.  
  180.  
  181. void free_args(struct args *args)
  182.     {
  183.     int i;
  184.     struct data_list *data, *temp;
  185.  
  186.     for(data = args->first_data; data;)
  187.         {
  188.         temp = data;
  189.         data = data->next;
  190.         free(temp);
  191.         }
  192.     for(i = 0; i != args->count; i++)
  193.         if((args->arg[i].type == ARGTYPE_STRING_MULTI)
  194.            || (args->arg[i].type == ARGTYPE_STRING_MULTISINGLE))
  195.             for(data = args->arg[i].data; data;)
  196.                 {
  197.                 temp = data;
  198.                 data = data->next;
  199.                 free(temp);
  200.                 }
  201.     free(args);
  202.     }
  203.  
  204.  
  205. void define_arg(struct args *args, int index, int type, char letter, char *longarg, void *def_value)
  206.     {
  207.     args->arg[index].type = type;
  208.     args->arg[index].letter = letter;
  209.     args->arg[index].longarg = longarg;
  210.     args->arg[index].data = def_value;
  211.     }
  212.